/***********************************************************************
Compile       : gcc -O3 -o design2 main2.c design.c
Usage         : ./design2 mode mode1 mode2 irflag bdflag dgflag pnflag N L inputfile 
                (./design2 0 0 0 0 0 0 0 11 12 Budding.txt)
mode          : 0 normal ; 1 cycled ; 2 triggled cycled
mode1         : 0 disallow self-activation ; 1 allow self_activation
mode2         : 0 no Restrictions ; 1 Restriction I ; 2 Restriction II; 3 Restriction I and II
irflag        : 1 irreducible solution only
bdflag        : 1 breakdown the designability by number of the links
dgflag	      : 1/2 breakdown the designability by number of the degrees(r<->g is counted for 2)
pnflag        : 1 print the solutions
N             : number of the nodes
L             : number of the steps        
Output        : n1 n2 min_link designability1 designability2
n1            : number of 1 in the process
n2            : number of 1 in the process (exclude the last fix point)
min_link      : minimum links of the qualified network
designability1: the minimum designability for one node
designability2: total designability
***********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "design.h"

int main (int argc, char *argv[])
{
	int N, L, i, j, k, l, n1, n2;
	int mode, mode1, mode2, irflag, bdflag, dgflag, pnflag;
	float ratio;
	FILE *fp;
	char buf[256];

	mode = atoi (argv[1]);
	mode1 = atoi (argv[2]);
	mode2 = atoi (argv[3]);
	irflag = atoi (argv[4]);
	bdflag = atoi (argv[5]);
	dgflag = atoi (argv[6]);
	pnflag = atoi (argv[7]);
	N = atoi (argv[8]);
	L = atoi (argv[9]);

	/* the degree of irreducible solution is zero */
	if (irflag)
		dgflag = 0;

	int pathway[L][N];
	double Links_dist[N * N + 1], Degree_dist[2 * N * N + 1];
	struct designability designability;
	struct solution solution[N];

	designability.NS2 = calloc (sizeof (int), N);
	designability.min_link = calloc (sizeof (int), N);

	for (i = 0; i < N; i++)
	{
		init_solution (&solution[i]);
	}

	fp = fopen (argv[10], "r");

	while (fgets (buf, 256, fp))
	{
		n1 = n2 = 0;
		for (i = 0; i < L; i++)
		{
			for (j = 0; j < N; j++)
			{
				fscanf (fp, "%d", &pathway[i][j]);
				n1 += pathway[i][j];
				if (i <= L - 3 || (i == L - 2 && mode != 2))
					n2 += pathway[i][j];
			}
			fgets (buf, 256, fp);
		}

		if (mode == 2)
			n2 --;

		/* Get the number of solution using enumerating algorithm */
		if (calc_design (N, L, pathway, mode, mode1, mode2, irflag, bdflag, dgflag, pnflag, 0, &designability, Links_dist, Degree_dist, solution) == 0)
			continue;

		if (pnflag)
		{
			for (i = 0; i < N; i++)
			{
				if (mode == 2 && i == 0)
					continue;

				printf ("Total Number of Soultion for Node %2d : %d\n", i, designability.NS2[i]);
				for (j = 0; j < solution[i].curr; j++)
				{
					printf ("Node %2d :", i);
					for (k = 0; k < N; k++)
					{
						if (solution[i].edge[j * N + k] == 0)
							printf (" n");
						else if (solution[i].edge[j * N + k] == 1)
							printf (" g");
						else if (solution[i].edge[j * N + k] == -1)
							printf (" r");
					}
					printf ("\n");
				}
			}
		}

		printf ("c %3d %3d %5d %lg\n", n2, designability.min_links, designability.NS2_min, designability.NS);

		if (bdflag)
		{
			for (i = 0; i <= N * N; i++)
			{
				if (Links_dist[i] > 0.1)
				{
					printf ("c Number of Links : %3d\tNumber of Solution : %lg\n", i, Links_dist[i]);
				}
			}
		}

		if (dgflag)
		{
			for (i = 0; i <= 2 * N * N; i++)
			{
				if (Degree_dist[i] > 0.1)
				{
					printf ("c Number of Degrees: %3d\tNumber of Solution : %lg\n", i, Degree_dist[i]);
				}
			}
		}

		for (i = 0; i < L; i++)
		{
			for (j = 0; j < N; j++)
			{
				printf ("%d ", pathway[i][j]);
			}
			printf ("\n");
		}
	}

	fclose (fp);

	for (i = 0; i < N; i++)
	{
		free_solution (&solution[i]);
	}
}
